 /////////////////////////////////////////////////////////////////////////////
// Name of module : ahb2ram                                                //
// Func           : ahb interface to ram                                   //
// Author         : heguangzu                                              //
// Simulator      :                                                        //
// Synthesizer    :                                                        //
// version 1.0    : made in Date: 2018.07.09                               //
/////////////////////////////////////////////////////////////////////////////


module ahb2ram_4
 (
                // AHB bus
                input  wire          hclk                , //由时钟sclk的下降沿 二分频得到
                input  wire          hresetn             ,
                input  wire [31:0]   hwdata              ,
                input  wire [31:0]   haddr               ,
                input  wire          hwrite              ,// 1 - Write, 0 - Read
                input  wire [2:0]    hsize               ,
                input  wire          hsel                ,
                input  wire [1:0]    htrans              ,
                output reg  [31:0]   hrdata              ,
                output reg           hready_out          ,

                input  wire          sclk                ,
                output reg  [3:0]    sel                 , // /* synthesis keep */                ,
                output reg  [31:0]   addr                , // /* synthesis keep */                ,
                output reg           wr_en               , // /* synthesis keep */                ,
                output reg  [31:0]   wdata               , // /* synthesis keep */               ,
                input  wire [31:0]   rdata0               ,
                input  wire [31:0]   rdata1               ,
                input  wire [31:0]   rdata2               ,
                input  wire [31:0]   rdata3               
);


reg        rw_flag                                          ; // /* synthesis keep */ ;
reg        data_en_reg                                      ; // /* synthesis keep */ ;
reg [5:0]  data_en_reg_d                                    ; // /* synthesis keep */ ;
reg        ready_reg                                        ; // /* synthesis keep */ ;

always@(posedge sclk)
begin
    case(addr[31:28])
            4'ha:    sel <= 4'b0001;
            4'hb:    sel <= 4'b0010;
            4'hc:    sel <= 4'b0100;
            4'hd:    sel <= 4'b1000;
            default:sel <= 4'b0000;
    endcase
end

always@(posedge sclk or negedge hresetn)
begin
    if(!hresetn)
        rw_flag <= 1'b0;
    else if(hsel && htrans[1] && (hclk==0) && hready_out) begin
        if( hwrite )
            rw_flag <= 1'b1;
        else
            rw_flag <= 1'b0;
    end
    else begin
        rw_flag <= rw_flag ;
    end
end

// assign wr_en = rw_flag ? data_en_reg_d[3] : 1'b0 ;

always@(posedge sclk )
begin
    if(!hresetn)
        wr_en <= 'b0;
    else if(data_en_reg_d[3] && rw_flag)begin
        wr_en <= 'b1;
    end
    else begin
        wr_en <= 0;
    end
    // wr_en <= data_en_reg_d[2] && rw_flag;
end

always@(posedge sclk )
begin
    if(!hresetn)
        wdata <= 'b0;
    else if(data_en_reg_d[0])begin
        wdata <= hwdata ;
    end
    else begin
        wdata <= wdata;
    end
end

always@(posedge sclk or negedge hresetn)
begin
    if(!hresetn)
        addr <= 32'h0000;
    else if( (hclk==0) && hready_out)
        begin
            if( hsel && htrans[1] ) begin
                addr[31:0] <= haddr[31:0];
            end
        end
end

always@(posedge sclk or negedge hresetn)
begin
    if(!hresetn)
        data_en_reg <= 1'b0;
    else if( hsel && htrans[1] && (hclk==0) && hready_out)
        begin
            data_en_reg <= 1'b1;
        end
    else
        data_en_reg <= 1'b0 ;
end


always@(posedge sclk or negedge hresetn)
begin
    if(!hresetn)
        ready_reg <= 1;
    else if( hsel && htrans[1] && (hclk==0) && hready_out)
            ready_reg <= 0;
    // else  if( data_en_reg_d== 4'b1000 )
    else  if( data_en_reg_d[5] == 1'b1 )
        ready_reg <= 1;
end

always@(posedge sclk or negedge hresetn)
begin
    if(!hresetn)
        hready_out <= 1;
    else if(hclk)
        hready_out <= ready_reg;
end

always@(posedge sclk or negedge hresetn)
begin
    if(!hresetn)
        data_en_reg_d <= 0;
    else
        data_en_reg_d[5:0] <= { data_en_reg_d[4:0] ,data_en_reg};
end


always@(posedge sclk or negedge hresetn)
begin
    if(!hresetn)
        hrdata[31:0] <= 0;
    else if(data_en_reg_d[5] == 1'b1 )
        hrdata[31:0] <= rdata0[31:0] | rdata1[31:0] | rdata2[31:0] | rdata3[31:0];
end

endmodule
